home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / doc / python-gst0.10 / examples / audioconcat.py < prev    next >
Encoding:
Python Source  |  2009-02-21  |  5.4 KB  |  193 lines

  1. #!/usr/bin/env python
  2. # -*- Mode: Python -*-
  3. # vi:si:et:sw=4:sts=4:ts=4
  4.  
  5. # audioconcat.py - Concatenates multiple audio files to single ogg/vorbis file
  6. # Uses the gnonlin elements (http://gnonlin.sf.net/)
  7. # Copyright (C) 2005 Edward Hervey <edward@fluendo.com>
  8. #               2006 Jason Gerard DeRose <jderose@jasonderose.org>
  9. #
  10. # This library is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU Library General Public
  12. # License as published by the Free Software Foundation; either
  13. # version 2 of the License, or (at your option) any later version.
  14. #
  15. # This library is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. # Library General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU Library General Public
  21. # License along with this library; if not, write to the
  22. # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. # Boston, MA 02111-1307, USA.
  24.  
  25. import sys
  26.  
  27. import gobject
  28. gobject.threads_init()
  29.  
  30. import pygst
  31. pygst.require('0.10')
  32. import gst
  33. from gst.extend.discoverer import Discoverer
  34.  
  35.  
  36.  
  37. class AudioDec(gst.Bin):
  38.     '''Decodes audio file, outputs at specified caps'''
  39.  
  40.     def __init__(self, location, caps):
  41.         gst.Bin.__init__(self)
  42.  
  43.         # Create elements
  44.         src = gst.element_factory_make('filesrc')
  45.         dec = gst.element_factory_make('decodebin')
  46.         conv = gst.element_factory_make('audioconvert')
  47.         rsmpl = gst.element_factory_make('audioresample')
  48.         ident = gst.element_factory_make('identity')
  49.  
  50.         # Set 'location' property on filesrc
  51.         src.set_property('location', location)
  52.  
  53.         # Connect handler for 'new-decoded-pad' signal 
  54.         dec.connect('new-decoded-pad', self.__on_new_decoded_pad)
  55.  
  56.         # Add elements to bin
  57.         self.add(src, dec, conv, rsmpl, ident)
  58.  
  59.         # Link *some* elements 
  60.         # This is completed in self.__on_new_decoded_pad()
  61.         src.link(dec)
  62.         conv.link(rsmpl)
  63.         rsmpl.link(ident, caps)
  64.  
  65.         # Reference used in self.__on_new_decoded_pad()
  66.         self.__apad = conv.get_pad('sink')
  67.  
  68.         # Add ghost pad
  69.         self.add_pad(gst.GhostPad('src', ident.get_pad('src')))
  70.  
  71.  
  72.     def __on_new_decoded_pad(self, element, pad, last):
  73.         caps = pad.get_caps()
  74.         name = caps[0].get_name()
  75.         print '\n__on_new_decoded_pad:', name
  76.         if 'audio' in name:
  77.             if not self.__apad.is_linked(): # Only link once
  78.                 pad.link(self.__apad)
  79.  
  80.  
  81.  
  82.  
  83. class AudioConcat:
  84.     '''Concatenates multiple audio files to single ogg/vorbis file'''
  85.  
  86.     caps = gst.caps_from_string('audio/x-raw-float, rate=44100, channels=2, endianness=1234, width=32')
  87.     
  88.     def __init__(self, infiles, outfile):
  89.         # These are used in iteration through infiles    
  90.         self.infiles = infiles
  91.         self.i = 0
  92.         self.start = 0L
  93.  
  94.         # The pipeline
  95.         self.pipeline = gst.Pipeline()
  96.  
  97.         # Create bus and connect 'eos' and 'error' handlers
  98.         self.bus = self.pipeline.get_bus()
  99.         self.bus.add_signal_watch()
  100.         self.bus.connect('message::eos', self.on_eos)
  101.         self.bus.connect('message::error', self.on_error)
  102.  
  103.         # Create elements
  104.         self.comp = gst.element_factory_make('gnlcomposition')
  105.         self.enc = gst.element_factory_make('vorbisenc')
  106.         self.mux = gst.element_factory_make('oggmux')
  107.         self.sink = gst.element_factory_make('filesink')
  108.  
  109.         # Connect handler for 'pad-added' signal 
  110.         self.comp.connect('pad-added', self.on_pad_added)    
  111.  
  112.         # Set 'location' property on filesink
  113.         self.sink.set_property('location', outfile)
  114.  
  115.         # Add elements to pipeline
  116.         self.pipeline.add(self.comp, self.enc, self.mux, self.sink)
  117.  
  118.         # Link *some* elements
  119.         # This in completed in self.on_pad_added()
  120.         gst.element_link_many(self.enc, self.mux, self.sink)
  121.  
  122.         # Reference used in self.on_pad_added()
  123.         self.apad = self.enc.get_pad('sink')
  124.  
  125.         # The MainLoop
  126.         self.mainloop = gobject.MainLoop()
  127.  
  128.         # Iterate through infiles
  129.         gobject.idle_add(self.discover)
  130.         self.mainloop.run()
  131.  
  132.  
  133.     def discover(self):
  134.         infile = self.infiles[self.i]
  135.         discoverer = Discoverer(infile)
  136.         discoverer.connect('discovered', self.on_discovered, infile)
  137.         discoverer.discover()
  138.         return False # Don't repeat idle call
  139.  
  140.  
  141.     def on_discovered(self, discoverer, ismedia, infile):
  142.         print '\non_discovered:', infile
  143.         discoverer.print_info()
  144.         if discoverer.is_audio:
  145.             dec = AudioDec(infile, self.caps)
  146.             src = gst.element_factory_make('gnlsource')
  147.             src.add(dec)
  148.             src.set_property('media-start', 0L)
  149.             src.set_property('media-duration', discoverer.audiolength)
  150.             src.set_property('start', self.start)
  151.             src.set_property('duration', discoverer.audiolength)
  152.             self.comp.add(src)
  153.             self.start += discoverer.audiolength
  154.         self.i += 1
  155.         if self.i < len(self.infiles):
  156.             gobject.idle_add(self.discover)
  157.         else:
  158.             if self.start > 0: # At least 1 infile is_audio and audiolength > 0
  159.                 self.pipeline.set_state(gst.STATE_PLAYING)
  160.             else:
  161.                 self.mainloop.quit()
  162.  
  163.  
  164.     def on_pad_added(self, element, pad):
  165.         caps = pad.get_caps()
  166.         name = caps[0].get_name()
  167.         print '\non_pad_added:', name
  168.         if name == 'audio/x-raw-float':
  169.             if not self.apad.is_linked(): # Only link once
  170.                 pad.link(self.apad)
  171.  
  172.  
  173.     def on_eos(self, bus, msg):
  174.         print '\non_eos'
  175.         self.mainloop.quit()
  176.  
  177.  
  178.     def on_error(self, bus, msg):
  179.         error = msg.parse_error()
  180.         print '\non_error:', error[1]
  181.         self.mainloop.quit()
  182.  
  183.  
  184.  
  185.  
  186. if __name__ == '__main__':
  187.     if len(sys.argv) >= 3:
  188.         AudioConcat(sys.argv[1:-1], sys.argv[-1])
  189.     else:
  190.         print 'Usage: %s <input_file(s)> <output_file>' % sys.argv[0]
  191.         print 'Example: %s song1.mp3 song2.ogg output.ogg' % sys.argv[0]
  192.